<template>
  <el-row>
    <el-col :span="24">
      <el-button-group>
        <el-button size="mini" type="primary" icon="el-icon-folder-opened" @click="printProcessXML">打印</el-button>
        <el-button size="mini" type="primary" icon="el-icon-folder-opened">打开文件</el-button>
        <el-button size="mini" type="primary" icon="el-icon-download">下载文件</el-button>
        <el-button size="mini" type="primary" icon="el-icon-receiving">保存</el-button>
      </el-button-group>
    </el-col>
  </el-row>

  <el-row>
    <el-col :span="18">
      <div class="canvas" ref="bpmn_canvas"></div>
    </el-col>
    <el-col :span="6">
      <div class="properties-panel">

        <el-form  :model="elementBaseInfo" size="mini" label-width="90px">
          <el-form-item label="类型">
            <el-input clearable v-model="elementBaseInfo.type" :disabled="true"/>
          </el-form-item>
          <el-form-item label="ID">
            <el-input clearable v-model="elementBaseInfo.id" @change="updateBaseInfo('id')"/>
          </el-form-item>
          <el-form-item label="名称">
            <el-input clearable v-model="elementBaseInfo.name" @change="updateBaseInfo('name')"/>
          </el-form-item>
          <el-form-item v-if="elementBaseInfo.type === 'bpmn:Process'">
            <el-checkbox v-model="elementBaseInfo.isExecutable" @change="updateBaseInfo('isExecutable')">isExecutable</el-checkbox>
          </el-form-item>
        </el-form>

        <el-form :model="flowConditionForm" label-width="90px" size="mini" v-if="elementBaseInfo.type === 'bpmn:SequenceFlow'">
          <el-form-item label="条件表达式">
            <el-input v-model="flowConditionForm.body" type="textarea" :rows="2" clearable @change="updateFlowCondition" />
          </el-form-item>
        </el-form>

      </div>
    </el-col>
  </el-row>
</template>

<script>
// 以下为bpmn工作流绘图工具的样式
import 'bpmn-js/dist/assets/diagram-js.css'
// 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'

import BpmnModeler from "bpmn-js/lib/Modeler"
import DefaultEmptyXML from "../bpmnModel/defaultEmptyXML"

export default {
  name: "bpmn",
  data() {
    return {
      processId: 'PR',
      processName: '采购流程',
      prefix: 'activiti',
      xml: '',
      elementBaseInfo: {
        type: '',
        id: '',
        name: '',
        isExecutable: false
      },
      flowConditionForm: {}
    }
  },
  mounted() {
    this.initBpmnModeler()
    this.createNewDiagram(this.xml)
  },
  methods: {
    initBpmnModeler() {
      const canvas = this.$refs.bpmn_canvas
      this.bpmnModeler = new BpmnModeler({
        container: canvas
      })
      this.initModelListeners()
    },
    initModelListeners() {
      const EventBus = this.bpmnModeler.get("eventBus")
      let that = this
      // 监听流程图点击
      EventBus.on('element.click', function(eventObj) {
        let element = eventObj ? eventObj.element : null
        that.initPropertiesPanel(element)
      })
      // 监听图形改变返回xml
      EventBus.on("commandStack.changed", function() {
      })
    },
    createNewDiagram(xml) {
      // 将字符串转换成图显示出来
      let newId = this.processId || `Process_${new Date().getTime()}`
      let newName = this.processName || `业务流程_${new Date().getTime()}`
      let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix)
      try {
        let { warnings } = this.bpmnModeler.importXML(xmlString)
        if (warnings && warnings.length) {
          warnings.forEach(warn => console.warn(warn))
        }
      } catch (e) {
        console.error(`[Process Designer Warn]: ${e.message || e}`)
      }
      this.initPropertiesPanel(null)
    },
    printProcessXML() {
      this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
        console.log(xml)
      })
    },
    // 初始化数据
    initPropertiesPanel(element) {
      const elementRegistry = this.bpmnModeler.get('elementRegistry');
      const userTaskList = elementRegistry.filter(
          (item) => console.log(item.type)
      )
      // 此时得到的userTaskList 便是流程图中所有的用户节点的集合
      console.log(userTaskList);
      console.log(elementRegistry.get('PR'));

      let activatedElement = element;
      if (!activatedElement) {
        console.log(elementRegistry)
        activatedElement =
            elementRegistry.find(el => el.type === "bpmn:Process") ??
            elementRegistry.find(el => el.type === "bpmn:Collaboration");
      }
      if (!activatedElement) return;
      console.log(`
              ----------
      select element changed:
                id:  ${activatedElement.id}
              type:  ${activatedElement.businessObject.$type}
              ----------
              `);
      console.log("businessObject: ", activatedElement.businessObject);
      this.bpmnElement = element
      let businessObject = activatedElement.businessObject
      let type = activatedElement.type
      this.elementBaseInfo.type = type
      this.elementBaseInfo.id = businessObject.id
      this.elementBaseInfo.name = businessObject.name
      this.elementBaseInfo.isExecutable = businessObject.isExecutable ?? false
      this.flowConditionForm = businessObject.conditionExpression ?? {}
    },
    updateBaseInfo(key) {
      let modeling = this.bpmnModeler.get("modeling")
      let attrObj = Object.create(null)
      attrObj[key] = this.elementBaseInfo[key]
      console.log(attrObj)
      console.log(this.bpmnElement)
      modeling.updateProperties(this.bpmnElement, attrObj)
    },
    updateFlowCondition() {
      let modeling = this.bpmnModeler.get("modeling")
      let moddle = this.bpmnModeler.get("moddle")
      let  body = this.flowConditionForm.body
      let condition
      if(body) {
        condition = moddle.create("bpmn:FormalExpression", { body });
      }
      modeling.updateProperties(this.bpmnElement, { conditionExpression: condition })
    }
  }
}
</script>

<style scoped>
.canvas {
  background-color: #ffffff;
  width: 100%;
  height: 600px;
}
.properties-panel {
  box-sizing: border-box;
  padding: 8px 8px;
  border-left: 1px solid #eeeeee;
  box-shadow: 0 0 8px #cccccc;
  max-height: 100%;
  overflow-y: scroll;
  height: 100%;
}
</style>